
from fastapi import APIRouter, Depends
from schemas.common import RETURN, ListRequest
from sqlalchemy import delete
from sqlalchemy.future import select
from fastapi_cache.decorator import cache
from starlette.responses import StreamingResponse

from database.mysql import get_async_session
from sqlmodel.ext.asyncio.session import AsyncSession
import models.admin.system.Menu as MenuModel
import models.admin.system.Admin as AdminModel
import models.admin.system.Link as LinkModel

from server.Base import BaseServer
from core.Depend import  has_permission
from utils import util

router = APIRouter(prefix="/Menu", tags=["菜单管理"])

# 添加菜单
@router.post("/add",summary="菜单添加")
async def add(menu: MenuModel.create_menu, session: AsyncSession = Depends(get_async_session),user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_add"))):
    # TODO:auths不能重复
    state = select(MenuModel.Menu).where(MenuModel.Menu.auths == menu.auths).where(MenuModel.Menu.menu_type == MenuModel.MenuTypeEnum.BUTTON)
    result = await session.exec(state)
    isHas:MenuModel.Menu = result.scalars().first()
    if isHas:
        return RETURN.fail("菜单编码已存在")
    await BaseServer(MenuModel.Menu).create(menu.dict())
    return RETURN.success("添加成功")

# 删除菜单
@router.delete("/delete",summary="菜单删除")
async def menu_delete(id: int, session: AsyncSession = Depends(get_async_session), user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_del"))):
    # 初始化一个集合用于存储所有需要删除的菜单ID
    ids_to_delete = set()
    # 定义一个递归函数来收集所有子菜单的ID
    async def collect_child_ids(parent_id: int):
        state = select(MenuModel.Menu.id).where(MenuModel.Menu.parent_id == parent_id)
        result = await session.exec(state)
        child_ids = result.scalars().all()
        for child_id in child_ids:
            await collect_child_ids(child_id)  # 递归收集子菜单ID
        ids_to_delete.update(child_ids)

    # 收集主菜单及其所有子菜单的ID
    await collect_child_ids(id)
    ids_to_delete.add(id)

    # TODO: 删除菜单权限关联的角色link
    delete_statement = delete(LinkModel.Role_Menu_Link).where(LinkModel.Role_Menu_Link.menu_id.in_(ids_to_delete))
    await session.exec(delete_statement)

    delete_statement = delete(MenuModel.Menu).where(MenuModel.Menu.id.in_(ids_to_delete))
    result = await session.exec(delete_statement)  # 使用 execute 而不是 exec
    await session.commit()  # 提交事务

    # 检查删除是否成功
    if result.rowcount > 0:
        return RETURN.success(f"删除成功，共删除 {result.rowcount} 个菜单项")
    else:
        return RETURN.fail("删除失败，没有找到对应的菜单项")

# 修改菜单
@router.put("/update",summary="菜单修改")
async def update(menu: MenuModel.edit_menu, session: AsyncSession = Depends(get_async_session),user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_edit"))):
    statement = select(MenuModel.Menu).where(MenuModel.Menu.auths == menu.auths).where(MenuModel.Menu.id != menu.id).where(MenuModel.Menu.menu_type == MenuModel.MenuTypeEnum.BUTTON)
    result = await session.exec(statement)
    isHas:MenuModel.Menu = result.scalars().first()
    if isHas:
        return RETURN.fail("菜单编码已存在")
    await BaseServer(MenuModel.Menu).update(menu.dict())
    return RETURN.success("修改成功")

# 查询菜单
@router.post("/list",summary="菜单列表")
async def list(request:ListRequest,user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_list"))):
    result = await BaseServer(MenuModel.Menu).list(request)
    return RETURN.success("查询成功",result)

# 查询菜单信息
@router.get("/info",summary="菜单信息")
async def info(id: int,user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_info"))):
    result = await BaseServer(MenuModel.Menu).get(id)
    if result:
        return RETURN.success("查询成功",result)
    else:
        return RETURN.fail("查询失败")
   
# 查询所有菜单
@router.get("/all", summary="所有菜单")
@cache(expire=10)
async def all(title:str = '',session: AsyncSession = Depends(get_async_session), user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_all"))):
    statement = select(MenuModel.Menu).where(MenuModel.Menu.title.like(f"%{title}%"))
    result = await session.exec(statement)
    datas = result.scalars().all()
    return RETURN.success("查询成功", datas)

@router.post("/export", summary="导出菜单")
async def export(request:ListRequest,user: AdminModel.redis_admin = Depends(has_permission("system_admin_menu_export"))):
    data, headers = await BaseServer(MenuModel.Menu).export(request.filter,request.fields)
    return StreamingResponse(util.generate_large_csv_from_sqlmodel(data), headers=headers)
